home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / gepackte_disketten / 1993 / 09_93_2.dms / 09_93_2.adf / Multitasking / Task-Erweitert.c < prev    next >
C/C++ Source or Header  |  1993-08-19  |  12KB  |  426 lines

  1. ; /*
  2. sc ignore=104,73 streq shortint strmerge link map task
  3. quit
  4. */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/memory.h>
  8. #include <exec/tasks.h>
  9. #include <devices/timer.h>
  10. #include <graphics/gfxbase.h>
  11. #include <graphics/gfx.h>
  12. #include <graphics/gfxmacros.h>
  13. #include <intuition/gadgetclass.h>
  14. #include <intuition/intuition.h>
  15. #include <intuition/intuitionbase.h>
  16. #include <libraries/gadtools.h>
  17. #include <proto/dos.h>
  18. #include <proto/exec.h>
  19. #include <proto/graphics.h>
  20. #include <proto/timer.h>
  21. #include <proto/intuition.h>
  22. #include <proto/gadtools.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <clib/macros.h>
  27.  
  28. #define STACKSIZE        (4*1024)
  29. #define TASKPRI        0
  30. #define TASKNAME        "Sample_Task"
  31.  
  32. #define SIG_SHOWMSG    0
  33. #define SIG_EXIT        1
  34. #define SIG_REPLY        2
  35. #define SIG_MAX        3
  36.  
  37. #define GAD_REPLY        0
  38. #define GAD_MODE        1
  39. #define GAD_MAX        2
  40.  
  41. struct MemTag {
  42.     struct MemList mt_ML;
  43.     struct MemEntry mt_ME;
  44. };
  45.  
  46. #define    TFLGF_TIMERSET    0x0001
  47. #define    TFLGF_WATCH        0x0002
  48. #define    TFLGF_BUSYWAIT    0x0004
  49.  
  50. struct TaskTag {
  51.     struct Task tt_Task;
  52.     ULONG tt_flags;
  53.     UBYTE volatile tt_SigBit[SIG_MAX];
  54.     struct Task* volatile tt_SigTask[SIG_MAX];
  55.     UBYTE* volatile tt_message;
  56.     UWORD volatile tt_msglen;
  57.     ULONG volatile tt_lcount;
  58.     struct MsgPort *tt_timerport;
  59.     struct timerequest *tt_timerequest,tt_cyclic;
  60.     struct Library *tt_timerbase;
  61.     struct timeval    volatile tt_tv0,tt_tvTskEntry,tt_tvUsed,tt_tvExpd;
  62.     int volatile tt_cpu;
  63. };
  64.  
  65. #define TSK_SHOWMSG(t) ((t)->tt_SigTask[SIG_SHOWMSG])
  66. #define TSK_EXIT(t)    ((t)->tt_SigTask[SIG_EXIT])
  67. #define TSK_REPLY(t)   ((t)->tt_SigTask[SIG_REPLY])
  68.  
  69. #define BIT_SHOWMSG(t) ((t)->tt_SigBit[SIG_SHOWMSG])
  70. #define BIT_EXIT(t)    ((t)->tt_SigBit[SIG_EXIT])
  71. #define BIT_REPLY(t)   ((t)->tt_SigBit[SIG_REPLY])
  72.  
  73. #define MSK_SHOWMSG(t) (1L << BIT_SHOWMSG(t))
  74. #define MSK_EXIT(t)    (1L << BIT_EXIT(t))
  75. #define MSK_REPLY(t)   (1L << BIT_REPLY(t))
  76.  
  77. #define    TimerBase (t->tt_timerbase)
  78.  
  79. extern struct IntuitionBase *IntuitionBase;
  80. extern struct Library *GadToolsBase;
  81. extern struct GfxBase *GfxBase;
  82.  
  83. void __interrupt Launch(void) {
  84.     struct TaskTag *t = (struct TaskTag*)FindTask(NULL);
  85.  
  86.     if(t->tt_flags & TFLGF_TIMERSET) {
  87.         t->tt_flags |= TFLGF_WATCH;
  88.         t->tt_lcount++;
  89.         GetSysTime(&t->tt_tvTskEntry);
  90.     }
  91. }
  92.  
  93. #define    MILLION    1000000L
  94.  
  95. void __interrupt Switch(void) {
  96.     struct TaskTag *t = (struct TaskTag*)FindTask(NULL);
  97.  
  98.     if(t->tt_flags & TFLGF_WATCH) {
  99.         t->tt_flags &= ~TFLGF_WATCH;
  100.         GetSysTime(&t->tt_timerequest->tr_time);
  101.         t->tt_tvExpd = t->tt_timerequest->tr_time;
  102.         SubTime(&t->tt_tvExpd,&t->tt_tv0);
  103.         SubTime(&t->tt_timerequest->tr_time,&t->tt_tvTskEntry);
  104.         AddTime(&t->tt_tvUsed,&t->tt_timerequest->tr_time);
  105.  
  106.         t->tt_cpu =    100L * (t->tt_tvUsed.tv_secs * MILLION
  107.                         + t->tt_tvUsed.tv_micro) / (t->tt_tvExpd.tv_secs
  108.                         * MILLION + t->tt_tvExpd.tv_micro);
  109.     }
  110. }
  111.  
  112. void __interrupt DisposeWindow(struct Window *w) {
  113.     struct Gadget *g = w->FirstGadget;
  114.     CloseWindow(w);
  115.     FreeGadgets(g);
  116. }
  117.  
  118. #define    G_WIDTH        100
  119. #define    G_HEIGHT        30
  120. #define    B_TOP(w)        ((w)->BorderTop + 5 + G_HEIGHT)
  121. #define    B_LEFT(w)    ((w)->BorderLeft + 3)
  122. #define    B_HEIGHT(w)    ((w)->Height - (w)->BorderTop -\
  123.                             (w)->BorderBottom - G_HEIGHT - 7)
  124. #define    B_WIDTH(w)    ((w)->Width - (w)->BorderLeft -\
  125.                             (w)->BorderRight - 6)
  126.  
  127. struct Gadget *wg[GAD_MAX];
  128.  
  129. struct Window* __interrupt InitWindow(void) {
  130.     APTR vi;    struct NewGadget ng;
  131.     struct Screen *ps;    struct Window *w;
  132.     struct Gadget *gl,*gad = NULL;
  133.  
  134.     if(ps = LockPubScreen(NULL)) {
  135.         if(vi = GetVisualInfoA(ps,NULL)) {
  136.             if(gad = CreateContext(&gl)) {
  137.                 static UBYTE *cycle_labels[] = {
  138.                     "Signal Wait","Busy Wait",NULL
  139.                 };
  140.  
  141.                 ng.ng_LeftEdge        = ps->WBorLeft + 3;
  142.                 ng.ng_TopEdge        = ps->BarHeight + 4;
  143.                 ng.ng_Width            = G_WIDTH;
  144.                 ng.ng_Height        = G_HEIGHT;
  145.                 ng.ng_VisualInfo    = vi;
  146.                 ng.ng_GadgetText    = "Reply";
  147.                 ng.ng_TextAttr        = ps->Font;
  148.                 ng.ng_Flags            = PLACETEXT_IN;
  149.                 ng.ng_GadgetID        = 0;
  150.                 ng.ng_UserData        = NULL;
  151.                 wg[GAD_REPLY] = gad = CreateGadget(BUTTON_KIND,
  152.                 gad,&ng,GA_Disabled,1L,TAG_DONE);
  153.  
  154.                 ng.ng_LeftEdge        = gad->LeftEdge + gad->Width + 1;
  155.                 ng.ng_Width            = G_WIDTH * 2 + 1;
  156.                 ng.ng_GadgetText    = NULL;
  157.                 ng.ng_GadgetID        = 1;
  158.                 wg[GAD_MODE] = gad = CreateGadget(CYCLE_KIND,gad,&ng,
  159.                 GTCY_Labels,cycle_labels,
  160.                 GTCY_Active,0L,TAG_DONE);
  161.  
  162.                 if(w = OpenWindowTags(NULL,
  163.                 WA_Flags,(ULONG)WFLG_DEPTHGADGET|WFLG_DRAGBAR,
  164.                 WA_IDCMP,(ULONG)IDCMP_GADGETUP,
  165.                 WA_InnerHeight,(ULONG)G_HEIGHT + 80L,
  166.                 WA_InnerWidth,(ULONG)G_WIDTH * 3 + 8,
  167.                 WA_Gadgets,gl,
  168.                 WA_Title,TASKNAME,
  169.                 WA_PubScreen,ps,
  170.                 TAG_DONE)) {
  171.  
  172.                     GT_RefreshWindow(w,NULL);
  173.  
  174.                     SetAPen(w->RPort,1);
  175.                     SetBPen(w->RPort,0);
  176.                     SetDrMd(w->RPort,JAM2);
  177.  
  178.                     DrawBevelBox(w->RPort,B_LEFT(w),
  179.                     B_TOP(w),B_WIDTH(w),B_HEIGHT(w),
  180.                     GT_VisualInfo,vi,GTBB_Recessed,1L,TAG_DONE);
  181.                 }
  182.                 else FreeGadgets(gl);
  183.             }
  184.             FreeVisualInfo(vi);
  185.         }
  186.         UnlockPubScreen(NULL,ps);
  187.     }
  188.     return(w);
  189. }
  190.  
  191. void __interrupt print(struct Window *w,UBYTE *text,int top,int len) {
  192.     SetAPen(w->RPort,0);
  193.     RectFill(w->RPort,B_LEFT(w) + 2,top -
  194.     w->RPort->Font->tf_Baseline,B_WIDTH(w) + 4,
  195.     top + w->RPort->Font->tf_YSize - w->RPort->Font->tf_Baseline);
  196.     Move(w->RPort,B_LEFT(w) + (B_WIDTH(w) - TextLength
  197.     (w->RPort,text,len)) / 2,top);
  198.     SetAPen(w->RPort,1);
  199.     Text(w->RPort,text,len);
  200. }
  201.  
  202.  
  203. void __interrupt ShowCPU(struct Window *w,struct TaskTag *t) {
  204.     UBYTE cpu_string[32];
  205.     sprintf(cpu_string,"Sw/s=%2ld, CPU (%ld/%ld) %2d%%",
  206.     t->tt_lcount / MAX(t->tt_tvExpd.tv_secs,1),
  207.     t->tt_tvUsed.tv_secs,t->tt_tvExpd.tv_secs,t->tt_cpu);
  208.     print(w,cpu_string,B_HEIGHT(w) / 2 -
  209.     w->RPort->Font->tf_Baseline + B_TOP(w),strlen(cpu_string));
  210. }
  211.  
  212. #define    AMIGAOS_V_37    37
  213.  
  214. void __saveds __interrupt SampleTask(void) {
  215.     struct TaskTag *t;
  216.     struct Window *w;
  217.  
  218.     t = (struct TaskTag*)FindTask(NULL);
  219.  
  220.     if(GfxBase = (struct GfxBase*)
  221.     OpenLibrary("graphics.library",AMIGAOS_V_37)) {
  222.  
  223.         if(IntuitionBase = (struct IntuitionBase*)
  224.         OpenLibrary("intuition.library",AMIGAOS_V_37)) {
  225.  
  226.             if(GadToolsBase = OpenLibrary("gadtools.library",AMIGAOS_V_37)) {
  227.  
  228.                 if(w = InitWindow()) {
  229.  
  230.                     if(t->tt_timerport = CreateMsgPort()) {
  231.                         if(t->tt_timerequest = (struct timerequest*)
  232.                         CreateIORequest(t->tt_timerport,sizeof(struct timerequest))) {
  233.                             if(OpenDevice(TIMERNAME,UNIT_VBLANK,
  234.                             t->tt_timerequest,0L) == 0) {
  235.                                 t->tt_cyclic = *t->tt_timerequest;
  236.                                 t->tt_timerbase = (struct Library*)
  237.                                 t->tt_timerequest->tr_node.io_Device;
  238.                                 GetSysTime(&t->tt_tv0);
  239.                                 t->tt_flags |= TFLGF_TIMERSET;
  240.  
  241.                                 t->tt_cyclic.tr_node.io_Command = TR_ADDREQUEST;
  242.                                 t->tt_cyclic.tr_time.tv_secs = 0L;
  243.                                 t->tt_cyclic.tr_time.tv_micro = 400000L;
  244.                                 SendIO(&t->tt_cyclic.tr_node);
  245.  
  246.                                 if((BIT_SHOWMSG(t) = AllocSignal(-1L)) != -1) {
  247.                                     TSK_SHOWMSG(t) = FindTask(NULL);
  248.                                     if((BIT_EXIT(t) = AllocSignal(-1L)) != -1) {
  249.                                         TSK_EXIT(t) = FindTask(NULL);
  250.                                         Signal(TSK_REPLY(t),MSK_REPLY(t));
  251.                                         while(1) {
  252.                                             ULONG sigset;
  253.  
  254.                                             if(t->tt_flags & TFLGF_BUSYWAIT) {
  255.                                                 sigset = SetSignal(0L,MSK_EXIT(t)
  256.                                                 | MSK_SHOWMSG(t)
  257.                                                 | 1L << t->tt_timerport->mp_SigBit
  258.                                                 | 1L << w->UserPort->mp_SigBit);
  259.                                             }
  260.                                             else {
  261.                                                 sigset = Wait(MSK_EXIT(t)
  262.                                                 | MSK_SHOWMSG(t)
  263.                                                 | 1L << t->tt_timerport->mp_SigBit
  264.                                                 | 1L << w->UserPort->mp_SigBit);
  265.                                             }
  266.  
  267.                                             if(sigset & 1L << t->tt_timerport->mp_SigBit) {
  268.                                                 t->tt_cyclic.tr_node.io_Command = TR_ADDREQUEST;
  269.                                                 t->tt_cyclic.tr_time.tv_secs = 0L;
  270.                                                 t->tt_cyclic.tr_time.tv_micro = 400000L;
  271.                                                 SendIO(&t->tt_cyclic.tr_node);
  272.                                                 ShowCPU(w,t);
  273.                                             }
  274.  
  275.                                             if(sigset & MSK_EXIT(t)) {
  276.                                                 break;
  277.                                             }
  278.  
  279.                                             if(sigset & MSK_SHOWMSG(t)) {
  280.  
  281.                                                 GT_SetGadgetAttrs(wg[GAD_REPLY],w,NULL,
  282.                                                 GA_Disabled,0L,TAG_DONE);
  283.                                                 RefreshGList(wg[0],w,NULL,1);
  284.  
  285.                                                 print(w,t->tt_message,
  286.                                                 B_TOP(w) + B_HEIGHT(w) / 2 +
  287.                                                 w->RPort->Font->tf_Baseline,t->tt_msglen);
  288.                                             }
  289.                                             if(sigset & 1L << w->UserPort->mp_SigBit) {
  290.                                                 struct IntuiMessage *imsg;
  291.  
  292.                                                 while(imsg = GT_GetIMsg(w->UserPort)) {
  293.                                                     ULONG im_code,im_class;
  294.                                                     APTR im_address;
  295.  
  296.                                                     im_class = imsg->Class;
  297.                                                     im_code = imsg->Code;
  298.                                                     im_address = imsg->IAddress;
  299.                                                     GT_ReplyIMsg(imsg);
  300.  
  301.                                                     switch(im_class) {
  302.                                                         case IDCMP_GADGETUP:
  303.                                                             switch(((struct Gadget*)
  304.                                                             im_address)->GadgetID) {
  305.                                                                 case GAD_REPLY:
  306.                                                                     GT_SetGadgetAttrs(wg[GAD_REPLY],
  307.                                                                     w,NULL,GA_Disabled,1L,TAG_DONE);
  308.                                                                     RefreshGList(wg[0],w,NULL,1);
  309.                                                                     Signal(TSK_REPLY(t),MSK_REPLY(t));
  310.                                                                     break;
  311.                                                                 case GAD_MODE:
  312.                                                                     switch(im_code) {
  313.                                                                         case 0:
  314.                                                                             t->tt_flags &= ~TFLGF_BUSYWAIT;
  315.                                                                             break;
  316.                                                                         case 1:
  317.                                                                             t->tt_flags |= TFLGF_BUSYWAIT;
  318.                                                                             break;
  319.                                                                         default:
  320.                                                                             break;
  321.                                                                     }
  322.                                                                     break;
  323.                                                                 default:
  324.                                                                     break;
  325.                                                             }
  326.                                                             break;
  327.                                                         default:
  328.                                                             break;
  329.                                                     }
  330.                                                 }
  331.                                             }
  332.                                         }
  333.                                         AbortIO(&t->tt_cyclic.tr_node);
  334.                                         WaitIO(&t->tt_cyclic.tr_node);
  335.                                         TSK_EXIT(t) = NULL;
  336.                                         FreeSignal(BIT_EXIT(t));
  337.                                     }
  338.                                     TSK_SHOWMSG(t) = NULL;
  339.                                     FreeSignal(BIT_SHOWMSG(t));
  340.                                 }
  341.                                 t->tt_flags &= ~(TFLGF_TIMERSET|TFLGF_WATCH);
  342.                                 CloseDevice(t->tt_timerequest);
  343.                             }
  344.                             DeleteIORequest(t->tt_timerequest);
  345.                         }
  346.                         DeleteMsgPort(t->tt_timerport);
  347.                     }
  348.                     DisposeWindow(w);
  349.                 }
  350.                 CloseLibrary(GadToolsBase);
  351.             }
  352.             CloseLibrary(&IntuitionBase->LibNode);
  353.         }
  354.         CloseLibrary(&GfxBase->LibNode);
  355.     }
  356.     Forbid();
  357.     Signal(TSK_REPLY(t),MSK_REPLY(t));
  358.     Wait(0L); /* Wait forever... */
  359. }
  360.  
  361. void main(void) {
  362.     struct TaskTag *ptt; struct MemList *pml;
  363.     struct MemTag aml; UBYTE SigBit; APTR stk;
  364.  
  365.     aml.mt_ML.ml_Node.ln_Type = NT_MEMORY;
  366.     aml.mt_ML.ml_Node.ln_Pri  = 0;
  367.     aml.mt_ML.ml_Node.ln_Name = TASKNAME;
  368.     aml.mt_ML.ml_NumEntries   = 2;
  369.     aml.mt_ML.ml_ME[0].me_Un.meu_Reqs = MEMF_PUBLIC|MEMF_CLEAR;
  370.     aml.mt_ML.ml_ME[0].me_Length      = sizeof(struct TaskTag);
  371.     aml.mt_ML.ml_ME[1].me_Un.meu_Reqs = MEMF_CLEAR;
  372.     aml.mt_ML.ml_ME[1].me_Length      = STACKSIZE;
  373.  
  374.     pml = AllocEntry(&aml.mt_ML);
  375.     if(!((ULONG)pml & (1L << 31))) {
  376.  
  377.         ptt = (struct TaskTag*) pml->ml_ME[0].me_Un.meu_Addr;
  378.         stk = (APTR)            pml->ml_ME[1].me_Un.meu_Addr;;
  379.  
  380.         ptt->tt_Task.tc_Node.ln_Pri  = TASKPRI;
  381.         ptt->tt_Task.tc_Node.ln_Type = NT_TASK;
  382.         ptt->tt_Task.tc_Node.ln_Name = TASKNAME;
  383.  
  384.         ptt->tt_Task.tc_SPLower = stk;
  385.         ptt->tt_Task.tc_SPReg   =
  386.         ptt->tt_Task.tc_SPUpper = (APTR)((ULONG)stk + STACKSIZE);
  387.  
  388.         NewList(&ptt->tt_Task.tc_MemEntry);
  389.         AddHead(&ptt->tt_Task.tc_MemEntry,&pml->ml_Node);
  390.  
  391.         if((SigBit = AllocSignal(-1L)) != -1) {
  392.  
  393.             BIT_REPLY(ptt) = SigBit;
  394.             TSK_REPLY(ptt) = FindTask(NULL);
  395.  
  396.             AddTask(&ptt->tt_Task,(APTR)SampleTask,0L);
  397.  
  398.             Disable();
  399.             ptt->tt_Task.tc_Launch  = Launch;
  400.             ptt->tt_Task.tc_Switch  = Switch;
  401.             ptt->tt_Task.tc_Flags  |= (TF_LAUNCH|TF_SWITCH);
  402.             Enable();
  403.  
  404.             Wait(MSK_REPLY(ptt));
  405.  
  406.             while(1) {
  407.                 int len;
  408.                 UBYTE msg_buf[128];
  409.                 Write(Output(),"Parent: ",8);
  410.                 len = Read(Input(),msg_buf,128);
  411.                 if(*msg_buf == '\n') break;
  412.                 ptt->tt_message = msg_buf;
  413.                 ptt->tt_msglen = len - 1;
  414.                 Signal(TSK_SHOWMSG(ptt),MSK_SHOWMSG(ptt));
  415.                 Wait(MSK_REPLY(ptt));
  416.             }
  417.  
  418.             Signal(TSK_EXIT(ptt),MSK_EXIT(ptt));
  419.             Wait(MSK_REPLY(ptt));
  420.             RemTask(&ptt->tt_Task);
  421.             FreeSignal(SigBit);
  422.         }
  423.     }
  424.     exit(0);
  425. }
  426.